package com.iplant.ams.serviceImpl.dao.ams;

import java.text.MessageFormat;
import java.util.*;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.sql.BaseDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import com.iplant.ams.service.po.ams.asset.AMSAssetClassification;

public class AMSAssetClassificationDAO extends BaseDAO {

    private static final Logger logger = LoggerFactory.getLogger(AMSAssetClassificationDAO.class);

    private static AMSAssetClassificationDAO Instance = null;

    private AMSAssetClassificationDAO() {
        super();
    }

    public static AMSAssetClassificationDAO getInstance() {
        if (Instance == null)
            Instance = new AMSAssetClassificationDAO();
        return Instance;
    }

    /**
     * 添加或修改
     */
    public int Update(AMSAssetClassification wAMSAssetClassification,
                      OutResult<Integer> wErrorCode) {
        int wResult = 0;
        try {
            if (wAMSAssetClassification == null)
                return 0;

            String wSQL;
            if (wAMSAssetClassification.getID() <= 0) {
                wSQL = MessageFormat.format("INSERT INTO {0}.ams_asset_classification(Name,Code,CreatorID,CreateTime," +
                                "Active,EditorID,EditTime,Description,ParentID,HasChild,IsDefault,TypeEnum) VALUES" +
                                "(:Name," +
                                ":Code,:CreatorID,:CreateTime,:Active,:EditorID,:EditTime,:Description,:ParentID," +
                                ":HasChild,:IsDefault,:TypeEnum);",
                        DBSchemas.Basic.getDBName());
            } else {
                wSQL = MessageFormat.format("UPDATE {0}.ams_asset_classification SET Name = :Name,Code = :Code," +
                                "CreatorID = :CreatorID,CreateTime = :CreateTime,Active = :Active,EditorID = " +
                                ":EditorID,EditTime = :EditTime,Description = :Description,ParentID = :ParentID," +
                                "HasChild = :HasChild,IsDefault = :IsDefault,TypeEnum=:TypeEnum WHERE ID = :ID;",
                        DBSchemas.Basic.getDBName());
            }

            wSQL = this.DMLChange(wSQL);

            Map<String, Object> wParamMap = new HashMap<>();

            wParamMap.put("ID", wAMSAssetClassification.ID);
            wParamMap.put("Name", wAMSAssetClassification.Name);
            wParamMap.put("Code", wAMSAssetClassification.Code);
            wParamMap.put("CreatorID", wAMSAssetClassification.CreatorID);
            wParamMap.put("CreateTime", wAMSAssetClassification.CreateTime);
            wParamMap.put("Active", wAMSAssetClassification.Active);
            wParamMap.put("EditorID", wAMSAssetClassification.EditorID);
            wParamMap.put("EditTime", wAMSAssetClassification.EditTime);
            wParamMap.put("Description", wAMSAssetClassification.Description);
            wParamMap.put("ParentID", wAMSAssetClassification.ParentID);
            wParamMap.put("HasChild", wAMSAssetClassification.HasChild);
            wParamMap.put("IsDefault", wAMSAssetClassification.IsDefault);
            wParamMap.put("TypeEnum", wAMSAssetClassification.TypeEnum);

            KeyHolder keyHolder = new GeneratedKeyHolder();
            SqlParameterSource wSqlParameterSource = new MapSqlParameterSource(wParamMap);

            this.update(wSQL, wSqlParameterSource, keyHolder);

            if (wAMSAssetClassification.getID() <= 0) {
                wResult = Objects.requireNonNull(keyHolder.getKey()).intValue();
                wAMSAssetClassification.setID(wResult);
            } else {
                wResult = wAMSAssetClassification.getID();
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 删除集合
     */
    public ServiceResult<Integer> DeleteList(List<AMSAssetClassification> wList,
                                             OutResult<Integer> wErrorCode) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            if (wList == null || wList.size() == 0)
                return wResult;

            List<String> wIDList = new ArrayList<>();
            for (AMSAssetClassification wItem : wList) {
                wIDList.add(String.valueOf(wItem.ID));
            }
            String wSql = MessageFormat.format("delete from {1}.ams_asset_classification WHERE ID IN({0}) ;",
                    String.join(",", wIDList), DBSchemas.Basic.getDBName());
            this.ExecuteSqlTransaction(wSql);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 查单条
     */
    public AMSAssetClassification SelectByID(int wID, OutResult<Integer> wErrorCode) {
        AMSAssetClassification wResult = new AMSAssetClassification();
        try {
            List<AMSAssetClassification> wList = SelectList(wID, "", "", -1, null, null, -1, -1,
                    Pagination.getDefault(),
                    wErrorCode);
            if (wList == null || wList.size() != 1)
                return wResult;
            wResult = wList.get(0);
        } catch (Exception e) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 条件查询集合
     */
    public List<AMSAssetClassification> SelectList(int wID, String wName, String wCode,
                                                   int wParentID, Calendar wStartTime, Calendar wEndTime,
                                                   int wActive, int wTypeEnum, Pagination wPagination,
                                                   OutResult<Integer> wErrorCode) {
        List<AMSAssetClassification> wResultList = new ArrayList<>();
        try {
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
            if (wStartTime == null) {
                wStartTime = wBaseTime;
            }
            if (wEndTime == null) {
                wEndTime = wBaseTime;
            }
            if (wStartTime.compareTo(wEndTime) > 0) {
                return wResultList;
            }

            String wSQL = MessageFormat.format(
                    "SELECT t.*,t1.Name CreatorName,t2.Name EditorName FROM {0}.ams_asset_classification t "
                            + " left join {0}.mbs_user t1 on t.CreatorID=t1.ID "
                            + " left join {0}.mbs_user t2 on t.EditorID=t2.ID "
                            + "WHERE  1=1  " +
                            "and ( :wID <= 0 or :wID = t.ID ) " +
                            "and ( :wActive < 0 or :wActive = t.Active ) " +
                            "and ( :wTypeEnum <= 0 or :wTypeEnum = t.TypeEnum ) " +
                            "and ( :wName is null or :wName = '''' or :wName = t.Name ) " +
                            "and ( :wCode is null or :wCode = '''' or :wCode = t.Code ) " +
                            "and ( :wStartTime <=str_to_date(''2010-01-01'', ''%Y-%m-%d'')  or :wStartTime <=  t" +
                            ".CreateTime ) " +
                            "and ( :wEndTime <=str_to_date(''2010-01-01'', ''%Y-%m-%d'')  or :wEndTime >=  t" +
                            ".CreateTime ) " +
                            "and ( :wParentID <= 0 or :wParentID = t.ParentID );",
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParamMap = new HashMap<>();

            wParamMap.put("wID", wID);
            wParamMap.put("wName", wName);
            wParamMap.put("wCode", wCode);
            wParamMap.put("wParentID", wParentID);
            wParamMap.put("wStartTime", wStartTime);
            wParamMap.put("wEndTime", wEndTime);
            wParamMap.put("wActive", wActive);
            wParamMap.put("wTypeEnum", wTypeEnum);

            wSQL = this.DMLChange(wSQL);

            wResultList = this.QueryForList(wSQL, wParamMap, wPagination, AMSAssetClassification.class);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }
        return wResultList;
    }
}
